home *** CD-ROM | disk | FTP | other *** search
/ Aminet 39 / Aminet 39 (2000)(Schatztruhe)[!][Oct 2000].iso / Aminet / game / shoot / Orbit_src.lha / Orbit / source / target.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-04  |  11.7 KB  |  542 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5.     22.06.2000 - some minor optimizations
  6. */
  7. /*
  8.  
  9. ORBIT, a freeware space combat simulator
  10. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  11.  
  12. This program is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU General Public License
  14. as published by the Free Software Foundation; either version 2
  15. of the License, or (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program; if not, write to the Free Software
  24. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  25.  
  26. */
  27.  
  28. #include "orbit.h"
  29.  
  30. void InitTargets()
  31. /*
  32.  *  Set up targets
  33.  */
  34. {
  35.   int t;
  36.  
  37.   for (t=0; t<NTARGETS; t++)
  38.   {
  39.     target[t].age = target[t].msl_idle = 0.0;
  40.     target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  41.  
  42.     target[t].hidden = 0;
  43.     target[t].friendly = 0;
  44.     target[t].invisible = 0;
  45.  
  46.     target[t].move_forward = target[t].move_backward =
  47.     target[t].move_up = target[t].move_down =
  48.     target[t].move_pitchleft = target[t].move_pitchright =
  49.     target[t].move_left = target[t].move_right = 0.0;
  50.  
  51.     target[t].weapon = NPLAYER_WEAPONS;
  52.     target[t].shields = 100.0;
  53.     target[t].maxshields = 100.0;
  54.  
  55.     strcpy (target[t].name, "Sparky");
  56.   }
  57. }
  58.  
  59. int FindTarget()
  60. /*
  61.  *  Find an unsed target
  62.  */
  63. {
  64.   int i, oldest;
  65.   double maxage;
  66.  
  67.   for (i=0; i<NTARGETS; i++)
  68.   {
  69.     if (target[i].age == 0.0) return (i);
  70.  
  71.     if (i == 0)
  72.     {
  73.       oldest = i;
  74.       maxage = target[i].age;
  75.     }
  76.     else
  77.     {
  78.       if (target[i].age > maxage)
  79.       {
  80.         maxage = target[i].age;
  81.         oldest = i;
  82.       }
  83.     }
  84.   }
  85.  
  86.   return (oldest);
  87. }
  88.  
  89. int FindTargetByName (char *name)
  90. {
  91.   int t;
  92.  
  93.   for (t=0; t<NTARGETS; t++)
  94.   {
  95.     if ( (target[t].age > 0.0) &&
  96.     (!strcasecmp (name, target[t].name)) )
  97.     {
  98.       return (t);
  99.     }
  100.   }
  101.  
  102.   return (-1);
  103. }
  104.  
  105. void PlaceTarget (double x, double y, double z)
  106. /*
  107.  *  Put a brand new target somewhere
  108.  */
  109. {
  110.   int t;
  111.  
  112.   t = FindTarget();
  113.  
  114.   target[t].pos[0] = x;
  115.   target[t].pos[1] = y;
  116.   target[t].pos[2] = z;
  117.  
  118.   target[t].view[0] = 1.0;
  119.   target[t].view[1] = target[t].view[2] = 0.0;
  120.  
  121.   target[t].up[0] = 0.0;
  122.   target[t].up[1] = 0.0;
  123.   target[t].up[2] = 1.0;
  124.  
  125.   Crossp (target[t].right, target[t].up, target[t].view);
  126.  
  127.   if (deltaT == 0.0)
  128.   {
  129.     target[t].age = 0.1;
  130.   }
  131.   else
  132.   {
  133.     target[t].age = deltaT;
  134.   }
  135.  
  136.   target[t].msl_idle = 0.0;
  137.  
  138.   target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  139.  
  140.   target[t].move_forward = target[t].move_backward =
  141.   target[t].move_up = target[t].move_down =
  142.   target[t].move_pitchleft = target[t].move_pitchright =
  143.   target[t].move_left = target[t].move_right = 0.0;
  144.  
  145.   strcpy (target[t].name, "Target");
  146.   target[t].list = model[0].list;
  147. }
  148.  
  149. void PlaceRandomTarget()
  150. /*
  151.  *  Put a target somewhere reasonable, randomly
  152.  */
  153. {
  154.   double x, y, z, th;
  155.  
  156.   th = 2.0 * rnd (6.28);
  157.  
  158.   x = planet[3].pos[0] + 2.0 * planet[3].radius * sin (th);
  159.   y = planet[3].pos[1] + 2.0 * planet[3].radius * cos (th);
  160.   z = planet[3].pos[2];
  161.  
  162.   PlaceTarget (x, y, z);
  163. }
  164.  
  165. void DestroyTarget (int t)
  166. /*
  167.  *  Destroy specified target
  168.  */
  169. {
  170.   int e;
  171.  
  172.   target[t].age = 0.0;
  173.  
  174.   player.score += target[t].score;
  175.  
  176.   /* If this was the locked target, unset lock */
  177.   CheckLock();
  178.  
  179.   /* Check to see if destroying this target triggers an event */
  180.   for (e=0; e<NEVENTS; e++)
  181.   {
  182.     if (event[e].pending &&
  183.     event[e].enabled &&
  184.     (event[e].trigger == EVENT_DESTROY) &&
  185.     (!strcasecmp (event[e].cvalue, target[t].name)) )
  186.     {
  187.       EventAction (e);
  188.     }
  189.   }
  190. }
  191.  
  192. static float lmodel_ambient[] = {
  193.   0.1, 0.1, 0.1, 1.0 }
  194. ;
  195.  
  196. void DrawTargets ()
  197. /*
  198.  *  Draw all the targets
  199.  */
  200. {
  201.   int i;
  202.  
  203.   glShadeModel (GL_FLAT);
  204.  
  205.   /* Need some ambient light for targets */
  206.   glLightfv (GL_LIGHT0, GL_AMBIENT, lmodel_ambient);
  207.  
  208.   for (i=0; i<NTARGETS; i++)
  209.   {
  210.     if (target[i].age > 0.0) DrawTarget (i);
  211.   }
  212.  
  213.   glShadeModel (GL_SMOOTH);
  214. }
  215.  
  216. void DrawTarget (int i)
  217. /*
  218.  *  Draw this target
  219.  */
  220. {
  221.   double v[3]; 
  222.  
  223.   /* Bump this target's age */
  224.   target[i].age += deltaT;
  225.  
  226.   /* Forget it if target is hidden or invisible */
  227.   if (target[i].hidden || target[i].invisible) return;
  228.  
  229.   /* Don't bother if target is too far away */
  230.   if (target[i].range2 > TARG_MAXRANGE2) return;
  231.  
  232.   /* Bail if couldn't load model */
  233.   if (target[i].model == (-1)) return;
  234.  
  235.   glPushMatrix();
  236.  
  237.   Vsub (v, target[i].pos, player.pos);
  238.   glTranslated (v[0], v[1], v[2]);
  239.  
  240.   /* Show up vector */
  241.   /*
  242.   glDisable (GL_LIGHTING);
  243.   glBegin (GL_LINES);
  244.     glColor3f (0.0, 1.0, 0.0);
  245.     glVertex3f (0.0, 0.0, 0.0);
  246.     glVertex3dv (target[i].up);
  247.   glEnd();
  248.   glEnable (GL_LIGHTING);
  249.   */
  250.  
  251.   /* Have target look in proper direction */
  252.   LookAt (target[i].view, target[i].up);
  253.  
  254.   /* Draw it */
  255.   glCallList (target[i].list);
  256.  
  257.   /* Draw bounding box */
  258.   /*
  259.   if (i == lock.target)
  260.   {
  261.     m = target[i].model;
  262.  
  263.     glDisable (GL_LIGHTING);
  264.     glColor3f (1.0, 1.0, 0.0);
  265.     glScaled (model[m].hibound[0] - model[m].lobound[0],
  266.               model[m].hibound[1] - model[m].lobound[1],
  267.               model[m].hibound[2] - model[m].lobound[2]);
  268.     glutWireCube (1.0);
  269.     glEnable (GL_LIGHTING);
  270.   }
  271.   */
  272.   glPopMatrix();
  273. }
  274.  
  275. void MoveTargets()
  276. /*
  277.  *  Move all the targets
  278.  */
  279. {
  280.   int t;
  281.   double v[3];
  282.  
  283.   for (t=0; t<NTARGETS; t++)
  284.   {
  285.     if (target[t].age > 0.0)
  286.     {
  287.       /* Determine distance from player */
  288.       Vsub (v, target[t].pos, player.pos);
  289.       target[t].range2 = Mag2 (v);
  290.  
  291.       if (!target[t].hidden)
  292.       {
  293.         target[t].age += deltaT;
  294.         target[t].msl_idle += deltaT;
  295.  
  296.         /* Give this target a chance to think */
  297.         if (target[t].range2 < TARG_MAXRANGE2) ThinkTarget (t);
  298.  
  299.         /* Now move it */
  300.         MoveTarget (t);
  301.       }
  302.     }
  303.   }
  304. }
  305.  
  306. void MoveTarget (int t)
  307. /*
  308.  *  Move this target
  309.  */
  310. {
  311.   double deltav[3], v[3], theta; 
  312.   int p;
  313.  
  314.   /* Is this a network game and this target is us? */
  315.   /*
  316.  if (am_client && (t == client[clientme.client].target)) return;
  317.  if (am_server && (t == client[server.client].target)) return;
  318. */
  319.   /* Compute angle to move, given time change */
  320.   theta = THETA * deltaT;
  321.  
  322.   /* Deltav will be change in velocity components due to thrust */
  323.   deltav[0] = deltav[1] = deltav[2] = 0.0;
  324.  
  325.   if (target[t].move_left > 0.0)
  326.   {
  327.     RotateAbout (v, target[t].view, target[t].up, -theta*target[t].move_left);
  328.     Vset (target[t].view, v);
  329.     Normalize (target[t].view);
  330.     Crossp (target[t].right, target[t].up, target[t].view);
  331.     Normalize (target[t].right);
  332.   }
  333.  
  334.   if (target[t].move_right > 0.0)
  335.   {
  336.     RotateAbout (v, target[t].view, target[t].up, theta*target[t].move_right);
  337.     Vset (target[t].view, v);
  338.     Normalize (target[t].view);
  339.     Crossp (target[t].right, target[t].up, target[t].view);
  340.     Normalize (target[t].right);
  341.   }
  342.  
  343.   if (target[t].move_up > 0.0)
  344.   {
  345.     RotateAbout (v, target[t].view, target[t].right, theta*target[t].move_up);
  346.     Vset (target[t].view, v);
  347.     Normalize (target[t].view);
  348.     Crossp (target[t].up, target[t].view, target[t].right);
  349.     Normalize (target[t].up);
  350.   }
  351.  
  352.   if (target[t].move_down > 0.0)
  353.   {
  354.     RotateAbout (v, target[t].view, target[t].right, -theta*target[t].move_down);
  355.     Vset (target[t].view, v);
  356.     Normalize (target[t].view);
  357.     Crossp (target[t].up, target[t].view, target[t].right);
  358.     Normalize (target[t].up);
  359.   }
  360.  
  361.   if (target[t].move_pitchright > 0.0)
  362.   {
  363.     RotateAbout (v, target[t].up, target[t].view, -theta*target[t].move_pitchright);
  364.     Vset (target[t].up, v);
  365.     Normalize (target[t].up);
  366.     Crossp (target[t].right, target[t].up, target[t].view);
  367.     Normalize (target[t].right);
  368.   }
  369.  
  370.   if (target[t].move_pitchleft > 0.0)
  371.   {
  372.     RotateAbout (v, target[t].up, target[t].view, theta*target[t].move_pitchleft);
  373.     Vset (target[t].up, v);
  374.     Normalize (target[t].up);
  375.     Crossp (target[t].right, target[t].up, target[t].view);
  376.     Normalize (target[t].right);
  377.   }
  378.  
  379.   if (target[t].move_forward > 0.0)
  380.   {
  381.     Vmul (v, target[t].view, target[t].move_forward*DELTAV*deltaT);
  382.     Vadd (deltav, deltav, v);
  383.   }
  384.  
  385.   if (target[t].move_backward > 0.0)
  386.   {
  387.     Vmul (v, target[t].view, -target[t].move_backward*DELTAV*deltaT);
  388.     Vadd (deltav, deltav, v);
  389.   }
  390.  
  391.   /* Compute change to velocity */
  392.   Vadd (target[t].vel, target[t].vel, deltav);
  393.  
  394.   /* Compute gravity's contribution */
  395.   if (gravity && (am_client || am_server))
  396.   {
  397.     Gravity (deltav, target[t].pos);
  398.     Vadd (target[t].vel, target[t].vel, deltav);
  399.   }
  400.  
  401.   /* Finaly, move target */
  402.   Vmul (v, target[t].vel, deltaT);
  403.   Vadd (target[t].pos, target[t].pos, v);
  404.  
  405.   target[t].move_forward = target[t].move_backward = 0.0;
  406.  
  407.   if ( (!am_client) && (!am_server) )
  408.   {
  409.     target[t].move_up = target[t].move_down =
  410.     target[t].move_pitchleft = target[t].move_pitchright =
  411.     target[t].move_left = target[t].move_right = 0.0;
  412.   }
  413.  
  414.   /* See if target[t] cratered on a planet */
  415.   if ((!am_client) && ((-1) != (p = InsidePlanet (target[t].pos))))
  416.   {
  417.     /* Make an explosion */
  418.     Vmul (v, target[t].pos, 1.05);
  419.     Boom (v, 1.0); 
  420.     if (am_server) 
  421.     {
  422.       NetTargetCratered (t, p); 
  423.     }
  424.     else 
  425.     {
  426.       DestroyTarget (t); 
  427.     }
  428.   }
  429.  
  430.   /* Regenerate target shields */
  431.   target[t].shields += target[t].shieldregen * deltaT;
  432.   if (target[t].shields > target[t].maxshields)
  433.   target[t].shields = target[t].maxshields;
  434. }
  435.  
  436. void TargetFiresMissile (int t)
  437. /*
  438.  *  Target t tries to fire missile at player
  439.  */
  440. {
  441.   if (target[t].msl_idle > weapon[target[t].weapon].idle)
  442.   {
  443.     /* Fire away! */
  444.     target[t].msl_idle = 0.0;
  445.     FireMissile (target[t].pos, target[t].vel, target[t].view,
  446.     target[t].friendly, target[t].weapon, t);
  447.   }
  448. }
  449.  
  450. void ShowTargetNames()
  451. {
  452.   int t;
  453.   char v, buf[128];
  454.   double v1[3];
  455.  
  456.   for (t=0; t<NTARGETS; t++)
  457.   {
  458.     if ( (target[t].age > 0.0) &&
  459.     (target[t].range2 < TARG_MAXRANGE2) &&
  460.     (!target[t].hidden) &&
  461.     (!target[t].invisible) )
  462.     {
  463.       if (target[t].friendly)
  464.       glColor3f (0.0, 0.8, 0.0);
  465.       else
  466.       glColor3f (0.8, 0.0, 0.0);
  467.  
  468.       Vsub (v1, target[t].pos, player.pos);
  469.       glRasterPos3dv (v1);
  470.       glGetBooleanv (GL_CURRENT_RASTER_POSITION_VALID, &v);
  471.       if (v)
  472.       {
  473.         if (target[t].range2 <= weapon[player.weapon].range2) 
  474.         {
  475.           sprintf (buf, "%s:%.0lf", target[t].name,  
  476.           KM_TO_UNITS1*sqrt(target[t].range2)); 
  477.         }
  478.         else 
  479.         {
  480.           strcpy (buf, target[t].name); 
  481.         }
  482.         Print (GLUT_BITMAP_HELVETICA_10, buf);
  483.       }
  484.     }
  485.   }
  486. }
  487.  
  488. int HitTarget (int m)
  489. /*
  490.  *  See if missile m hit any target.  -1 if not.
  491.  */
  492. {
  493.   int t, mdl, valid;
  494.   double v1[3], d;
  495.  
  496.   /* Loop through targets */
  497.   for (t=0; t<NTARGETS; t++)
  498.   {
  499.     /* See if we should even check this target */
  500.     if (!am_client && !am_server)
  501.     {
  502.       valid = (target[t].age > 0.0) &&
  503.       (!target[t].hidden) &&
  504.       (msl[m].friendly != target[t].friendly);
  505.     }
  506.     else
  507.     {
  508.       valid = (target[t].age > 0.0) &&
  509.       (!target[t].hidden) &&
  510.       (t != msl[m].owner);
  511.     }
  512.  
  513.     if (valid)
  514.     {
  515.       /* Get coords relative to target */
  516.       Vsub (v1, msl[m].pos, target[t].pos);
  517.  
  518.       /* Get target's model */
  519.       mdl = target[t].model;
  520.  
  521.       /* Check each axis by projecting v1 and checking bounding box */
  522.       d = Dotp (v1, target[t].view);
  523.       if ( (d < model[mdl].lobound[0]) ||
  524.       (d > model[mdl].hibound[0]) ) continue;
  525.  
  526.       d = Dotp (v1, target[t].right);
  527.       if ( (d < model[mdl].lobound[1]) ||
  528.       (d > model[mdl].hibound[1]) ) continue;
  529.  
  530.       d = Dotp (v1, target[t].up);
  531.       if ( (d < model[mdl].lobound[2]) ||
  532.       (d > model[mdl].hibound[2]) ) continue;
  533.  
  534.       /* If we get here, it's a hit! */
  535.       return (t);
  536.     }
  537.   }
  538.  
  539.   /* Nope */
  540.   return (-1);
  541. }
  542.